<?php
/**
 * XmuSlh, web platform of Student Association Federation of Xiamen University
 * 
 * Rewritting one or some pages of StatusNet. 
 * To get the original version, please visit <http://status.net/>.
 * 
 * StatusNet, the distributed open-source microblogging tool
 * 
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * A wrapper on uploaded data files.
 * 
 * Makes it slightly easier to accept an data file from upload.
 * 
 * 一个用用于接收资料文件上传的包装类.
 * 
 * @author		ytukie <ytukie@gmail.com>
 * @version		0.2
 * 
 * 0.2)  Adjusts the error handlers, using more exceptions.
 */

// XmuSlh only.
if ( !defined('XMUSLH')) { exit(1); }

// Requirements.
require_once INSTALLDIR . '/lib/slh_util.php';
require_once INSTALLDIR . '/classes/File.php';

// Definitions.
// define('DATAFILE_ERROR_INVALIDATEDFILE',			1);

class DataFile
{
	/**
	 * The upload method!
	 */
	static function fromUpload($param = 'upload')
	{
		if ( !isset($_FILES[$param])) {
			return false;
		}
		
		switch ($_FILES[$param]['error']) {
			case UPLOAD_ERR_OK: // success, jump out.
				break;
			case UPLOAD_ERR_INI_SIZE:
			case UPLOAD_ERR_FORM_SIZE:
				throw new Exception('文件大小超过了限制.');
			case UPLOAD_ERR_PARTIAL:
				@unlink($_FILES[$param]['tmp_name']);
				throw new Exception('文件上传不完整, 可能与网络环境有关.');
			case UPLOAD_ERR_NO_FILE:
				// No file, probably just a non-AJAX submission.
				throw new Exception('请选择上传的文件.');
			default:
				// FIXME: To log?
				slh_log(LOG_ERR, __METHOD__ . ": Unkwon upload error " .
						$_FILES[$param]['error']);
				throw new Exception('系统错误.');
		}
		
		// The file name.
		$originalname = $_FILES[$param]['name'];
		
		// The mimetype.
		$mimetype = $_FILES[$param]['type'];

		// The size.
		$size = $_FILES[$param]['size'];
		
// Check the size of the file.
		if ($size > DataFile::maxFileSizeInt()) {
			return false;
		}
		
		// Get the formatted filename.
		$filename = File::filename($originalname, $mimetype);
		
		// The path.
		$filepath = File::path($filename);
		
		// The url.
		$fileurl = File::url($filename);
		
		if (move_uploaded_file($_FILES[$param]['tmp_name'], $filepath)) {
			// Success.
			$file = new File();
			$file->filename = $filename;
			$file->mimetype = $mimetype;
			$file->originalname = $originalname;
			$file->size = $size;
			
			return $file;			
		} else {
			// Failed.
			@unlink($_FILES[$param]['tmp_name']);
			@unlink($filepath);
			
			throw new Exception('系统错误, 文件操作受到限制.');
		}
	}
	
	static function maxFileSize()
	{
		$value = DataFile::maxFileSizeInt();
		
		if ($value > 1024 * 1024) {
			$value = $value / (1024 * 1024);
			return $value . 'MB';
		} else if ($value > 1024) {
			return $value . 'KB';
		} else {
			return $value . 'DB';
		}
	}
	
	static function maxFileSizeInt()
	{
		return min(DataFile::strToInt(ini_get('post_max_size')),
				   DataFile::strToInt(ini_get('upload_max_filesize')),
				   DataFile::strToInt(ini_get('memory_limit')),
				   DataFile::strToInt(slh_config('file', 'maxfilesize')));
	}
	
	static function strToInt($str)
	{
		$uint = substr($str, -1);
		$num = substr($str, 0, -1);
		
		switch(strtoupper($uint)) {
			case 'G':
				$num *= 1024;
			case 'M':
				$num *= 1024;
			case 'K':
				$num *= 1024;
		}
		
		return $num;
	}
}

?>